<template>
	<view class="media-box">
		<view class="media-item" v-for='(item, index) in list' :key="index"
			:style="{width: itemSize.width, height: itemSize.height}">
			<media-show-item :ref="'item_'+index" :itemSize='itemSize' :mediaData='item'
				@tapImage='tapImage($event, index)' @tapVideo='tapVideo($event, index)'>
				<template v-slot:topLeft>
					<view class="corner-button delete-button" @click.stop="tapDelete(item, index)" v-if='ableDelete'>
						<uni-icons type="clear" color="#ff2525" size="26"></uni-icons>
					</view>
				</template>
				<template v-slot:topRight>
					<view class="corner-button download-button" @click.stop="tapDownload(item, index)"
						v-if='ableDownload'>
						<uni-icons type='cloud-download-filled' color='#ff2525' size='26'></uni-icons>
					</view>
				</template>
				<template v-slot:cover>
					<view class="cover-bg" v-if='mediaShowDownloadStatusList[index].isDownloading'>
						<view class="cover-content">
							<cu-circle :cid="'downloading-'+index" size='50' :transparent="true" strokeColor="#888"
								progressColor="#fff" :strokeWidth="6"
								:percent='mediaShowDownloadStatusList[index].progress'>
								<view class="progress">
									{{mediaShowDownloadStatusList[index].progress}}%
								</view>
							</cu-circle>
						</view>
					</view>
				</template>
			</media-show-item>
		</view>
	</view>
</template>

<script>
	import {
		checkAuthSetting,
		logError,
		px2rpx
	} from '../../utils/index.js'
	import {
		ENUM_MEDIA_DOWNLOAD_STATUS,
		ENUM_MEDIA_TYPE
	} from "../../static/enum.js"
	import ComponentMixin from "../../mixins/common-component-mixin.js";
	import mediaShowItem from '../cu-media-item/cu-media-item.vue'
	import {
		DownloadParam
	} from '../../utils/request/requestModels.js';
	import {
		downloadRequest
	} from "../../utils/request/index.js"
	import cuCircle from "../cu-circle/cu-circle.vue";
	class MediaDownloadStatus {
		constructor() {
			this.status = ENUM_MEDIA_DOWNLOAD_STATUS.WAITING.value;
			this.progress = 0;
			this.isDownloading = false;
		}
	}
	export default {
		mixins: [ComponentMixin],
		components: {
			mediaShowItem,
			cuCircle
		},
		name: "media-show",
		props: {
			// 是否允许删除
			ableDelete: {
				type: Boolean,
				default: true
			},
			// 是否允许下载
			ableDownload: {
				type: Boolean,
				default: true,
			},
			// 展示数据
			list: {
				type: Array,
				default: () => [],
				validator: function(value) {
					let result = true;
					value.forEach((item, index) => {
						if (!(item.imageType && (item.imageType == ENUM_MEDIA_TYPE.IMAGE.value || item
									.imageType ==
									ENUM_MEDIA_TYPE.VIDEO.value) &&
								item.imageUrl)) {
							result = false;
							logError(`media-show list index:${index} is error data`);
						}
					})
					return result;
				}
			},
			// 列数
			colCount: {
				type: Number,
				default: 3,
				validator: function(value) {
					return typeof value == 'number' && value >= 1 && value <= 5
				}
			},
			// 宽高比（高度相对于宽度的比值）
			aspectRatio: {
				type: Number,
				default: 1.2,
				validator: function(value) {
					return typeof value == 'number' && value > 0
				}
			},
			// 是否自动计算宽高
			autoCalcItemSize: {
				type: Boolean,
				default: true, // false 时  需要在恰当的时候手动调用 resetItemSize方法
			}
		},
		data() {
			return {
				itemSize: {
					width: '',
					height: ''
				},
				mediaShowDownloadStatusList: [],
				downloading: false
			};
		},
		watch: {
			// 监听列表数变动，修正item尺寸
			colCount: {
				handler: function(newVal) {
					if (this.autoCalcItemSize) {
						this.resetItemSize(newVal);
					}
				},
				immediate: true
			},
			list: {
				handler: function(n) {
					if (n) {
						this.initDownloadStatusList(n.length);
					}
				},
				deep: true,
				immediate: true
			}
		},
		mounted() {},
		destroyed() {},
		methods: {
			// 初始化下载状态列表
			initDownloadStatusList() {
				this.mediaShowDownloadStatusList = new Array(this.list.length).fill({}).map((item) => {
					return new MediaDownloadStatus();
				})
			},
			// 修正item尺寸
			resetItemSize(col) {
				const query = uni.createSelectorQuery().in(this);
				query.select('.media-box').boundingClientRect();
				query.exec((res) => {
					if (res[0]) {
						const width = res[0].width;
						if (width) {
							let calcWidth = px2rpx(width / (col ? col : this.colCount))
							this.itemSize.width = `${calcWidth-10}rpx`;
							this.itemSize.height = `${calcWidth * this.aspectRatio -10}rpx`;
						}
					}
				})
			},
			// 点击图片
			tapImage(url, index) {
				this.$refs['item_' + index][0].previewImage(this.list.filter(item => {
					return item.imageType == ENUM_MEDIA_TYPE.IMAGE.value
				}).map(item => {
					return item.imageUrl
				}), url)
			},
			// 点击视频
			tapVideo(url, index) {
				this.$refs['item_' + index][0].previewVideo(url)
			},
			// 点击删除
			tapDelete(media, index) {
				if (this.downloading) {
					uni.showToast({
						title: '正在下载中，请稍后操作',
						icon: 'none'
					})
					return;
				};
				let result = this.list;
				result.splice(index, 1);
				this.$emit('delete', {
					deleteIndex: index,
					deleteMedia: media,
					deleteResult: result
				})
			},
			// 点击下载
			tapDownload(media, index) {
				if (this.downloading) {
					uni.showToast({
						title: '正在下载中，请稍后操作',
						icon: 'none'
					})
					return;
				};
				this.downloading = true;
				this.$set(this.mediaShowDownloadStatusList[index], "status", ENUM_MEDIA_DOWNLOAD_STATUS.WAITING.value)
				this.$set(this.mediaShowDownloadStatusList[index], "progress", 0)
				// 检查写入权限
				checkAuthSetting('writePhotosAlbum').then(res => {
					this.$set(this.mediaShowDownloadStatusList[index], "status", ENUM_MEDIA_DOWNLOAD_STATUS
						.DOWNLOADING.value)
					this.$set(this.mediaShowDownloadStatusList[index], "isDownloading", true)
					// 根据类型执行下载
					switch (media.imageType) {
						case ENUM_MEDIA_TYPE.IMAGE.value:
							return this.downloadAndSaveImage(media.imageUrl, index);
						case ENUM_MEDIA_TYPE.VIDEO.value:
							return this.downloadAndSaveVideo(media.imageUrl, index);
						default:
							logError(`media-show list index:${index} is error data`);
							return Promise.reject('media type error');
					}
				}).then(res => {
					// 更新状态
					this.$set(this.mediaShowDownloadStatusList[index], "status", ENUM_MEDIA_DOWNLOAD_STATUS.SUCCESS
						.value)
					this.$set(this.mediaShowDownloadStatusList[index], "progress", 0)
					this.$set(this.mediaShowDownloadStatusList[index], "isDownloading", false)
					uni.showToast({
						title: '下载保存成功',
						icon: 'success',
					})
				}).catch(errMsg => {
					// 更新状态
					this.$set(this.mediaShowDownloadStatusList[index], "status", ENUM_MEDIA_DOWNLOAD_STATUS.FAIL
						.value)
					this.$set(this.mediaShowDownloadStatusList[index], "progress", 0)
					this.$set(this.mediaShowDownloadStatusList[index], "isDownloading", false)
					uni.showToast({
						title: errMsg ? errMsg : "下载保存失败",
						icon: 'none'
					})
				}).finally(() => {
					this.downloading = false;
				})
			},
			// 下载并保存视频
			downloadAndSaveVideo(url, index) {
				let fileName = new Date().valueOf();
				let videoPath;
				// #ifdef MP-WEIXIN
				videoPath = wx.env.USER_DATA_PATH + '/' + fileName + '.mp4';
				// #endif
				// #ifndef MP-WEIXIN
				videoPath = fileName + '.mp4';
				// #endif
				// 下载
				const downloadParam = new DownloadParam({
					useBaseUrl: false,
					url,
					filePath: videoPath,
					signal: {
						onProgressUpdate: (res) => {
							const {
								progress
							} = res;
							this.$set(this.mediaShowDownloadStatusList[index], "progress", progress)
						}
					}
				})
				return downloadRequest(downloadParam).then(downloadRes => {
					// 保存
					let tempFilePath = downloadRes.filePath;
					return new Promise((resolve, reject) => {
						uni.saveVideoToPhotosAlbum({
							filePath: tempFilePath,
							success: (saveRes) => {
								resolve()
							},
							fail: (saveError) => {
								reject('保存失败');
							},
							complete: () => {
								let fileMgr = uni.getFileSystemManager();
								fileMgr.unlink({ //删除临时文件
									filePath: videoPath,
								})
							}
						})
					})
				})
			},
			// 下载并保存图片
			downloadAndSaveImage(url, index) {
				const downloadParam = new DownloadParam({
					useBaseUrl: false,
					url,
					signal: {
						onProgressUpdate: (res) => {
							const {
								progress
							} = res;
							this.$set(this.mediaShowDownloadStatusList[index], "progress", progress)
						}
					}
				})
				// 下载
				return downloadRequest(downloadParam).then(res => {
					// 保存
					return new Promise((resolve, reject) => {
						uni.saveImageToPhotosAlbum({
							filePath: res.tempFilePath,
							success: (saveRes) => {
								resolve()
							},
							fail: (saveError) => {
								reject('保存失败');
							},
						})
					})
				})
			}
		},
	}
</script>

<style lang="scss" scoped>
	.media-box {
		display: flex;
		flex-direction: row;
		flex-wrap: wrap;
		margin-left: 10rpx;

		.media-item {
			display: flex;
			flex-direction: column;
			margin-right: 10rpx;
			margin-bottom: 10rpx;
			border-radius: 14rpx;
			overflow: hidden;

			&::last-child {
				margin-right: 0;
			}

			.corner-button {
				width: 100%;
				height: 100%;
				display: flex;
				flex-direction: column;
				background: #ffffff44;
			}

			.delete-button {
				align-items: flex-start;
				justify-content: flex-start;
				border-bottom-right-radius: 50%;
			}

			.download-button {
				align-items: flex-end;
				justify-content: flex-start;
				border-bottom-left-radius: 50%;
			}

			.cover-bg {
				width: 100%;
				height: 100%;
				background: #88888844;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
				position: absolute;
				z-index: 1;

				.cover-content {
					display: flex;
					flex-direction: column;
					align-items: center;
				}
			}
		}
	}
</style>